package cn.jinjimi.domain.data.net;

import cn.jinjimi.app.controller.event.NetworkErrorEvent;
import cn.jinjimi.domain.Dispatcher;
import cn.jinjimi.domain.ServiceManager;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.Request;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

/**
 * Created by zhenhua on 16/9/7.
 */
public class APICallAdapterFactory extends CallAdapter.Factory {

    @Override
    public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {

        if (getRawType(returnType) != Call.class) {
            return null;
        }

        final Type responseType = Utils.getCallResponseType(returnType);

        return new CallAdapter<Call<?>>() {
            @Override
            public Type responseType() {
                return responseType;
            }

            @Override
            public <R> Call<R> adapt(Call<R> call) {
                return new ComfortableCall<>(call);
            }
        };
    }

    public static class ComfortableCall<T> implements Call<T>{

        private final Call<T> delegate;

        public ComfortableCall(Call<T> call){
            this.delegate = call;
        }


        @Override
        public Response<T> execute() throws IOException{
            try {
                return delegate.execute();
            } catch (IOException e){
                ServiceManager.getService(Dispatcher.class)
                        .dispatch(new NetworkErrorEvent());
            }

            return null;
        }

        @Override
        public void enqueue(Callback<T> callback) {
            delegate.enqueue(callback);
        }

        @Override
        public boolean isExecuted() {
            return delegate.isExecuted();
        }

        @Override
        public void cancel() {
            delegate.cancel();
        }

        @Override
        public boolean isCanceled() {
            return delegate.isCanceled();
        }

        @Override
        public Call<T> clone() {
            return new ComfortableCall<>(delegate.clone());
        }

        @Override
        public Request request() {
            return delegate.request();
        }
    }


}
